package inventory

import (
	"fmt"
	"github.com/fatih/color"
	"github.com/xuri/excelize/v2"
	"gosh/pkg/model"
	"strconv"
	"strings"
)

func ImportToDB() {
	insertFromExcel(ImportConfig.Path)
}

func insertFromExcel(filePath string) {
	f, err := excelize.OpenFile(filePath)
	if err != nil {
		color.Red("open %s failed, error:%s", filePath, err.Error())
		return
	}
	bastionRows, err := f.GetRows("bastion")
	if err == nil {
		for lineNo, bastionRow := range bastionRows {
			if lineNo == 0 {
				continue
			}
			if len(bastionRow) < 3 {
				color.Red("the number of elements is less than 3; line: %d", lineNo)
				continue
			}
			var bastion = &model.Bastion{
				ConnectIP:        getValueFromRow(bastionRow, 0),
				PrivateIP:        getValueFromRow(bastionRow, 1),
				PublicIP:         getValueFromRow(bastionRow, 2),
				SSHPort:          parseStrToInt(getValueFromRow(bastionRow, 3), 22),
				SSHUser:          getValueFromRow(bastionRow, 4),
				SSHPassword:      getValueFromRow(bastionRow, 5),
				SSHKeyFile:       getValueFromRow(bastionRow, 6),
				SSHKeyPassphrase: getValueFromRow(bastionRow, 7),
				Vendor:           getValueFromRow(bastionRow, 8),
				Region:           getValueFromRow(bastionRow, 9),
			}
			if err = bastion.InsertOrUpdate(); err != nil {
				color.Red("insert bastion in line:%d failed,error:%s", lineNo, err.Error())
				continue
			}
			color.Green("insert line:%d,bastion %s succeed", lineNo, bastion.ConnectIP)
		}
	} else if _, ok := interface{}(err).(excelize.ErrSheetNotExist); ok {
		color.Yellow("sheet %s not exist", "bastion")
	} else {
		color.Red("get bastion sheet failed, error:%s", err.Error())
		return
	}

	hostRows, err := f.GetRows("host")

	if err == nil {
		for lineNo, hostRow := range hostRows {
			if lineNo == 0 {
				continue
			}
			if len(hostRow) < 11 {
				color.Red("the number of elements is less than 11; line: %d", lineNo)
				continue
			}
			var host = &model.Host{
				Name:             fmt.Sprintf("%s-%s-%s", getValueFromRow(hostRow, 9), getValueFromRow(hostRow, 10), getValueFromRow(hostRow, 0)),
				PrivateIP:        getValueFromRow(hostRow, 0),
				PublicIP:         getValueFromRow(hostRow, 1),
				ConnectIP:        getValueFromRow(hostRow, 2),
				BastionIP:        getValueFromRow(hostRow, 3),
				SSHPort:          parseStrToInt(getValueFromRow(hostRow, 4), 22),
				SSHUser:          getValueFromRow(hostRow, 5),
				SSHPassword:      getValueFromRow(hostRow, 6),
				SSHKeyFile:       getValueFromRow(hostRow, 7),
				SSHKeyPassphrase: getValueFromRow(hostRow, 8),
				Vendor:           getValueFromRow(hostRow, 9),
				Region:           getValueFromRow(hostRow, 10),
				Project:          getValueFromRow(hostRow, 11),
				Env:              getValueFromRow(hostRow, 12),
				App:              getValueFromRow(hostRow, 13),
			}
			if err = host.InsertOrUpdate(); err != nil {
				color.Red("insert host in line:%d failed,error:%s", lineNo, err.Error())
				continue
			}
			color.Green("insert line:%d,host %s succeed", lineNo, host.ConnectIP)
		}

	} else if _, ok := interface{}(err).(excelize.ErrSheetNotExist); ok {
		color.Yellow("sheet %s not exist", "host")
	} else {
		color.Red("get host sheet failed, error:%s", err.Error())
		return
	}
}

func parseStrToInt(s string, defaultValue int) int {
	i, err := strconv.ParseInt(s, 10, 64)
	if err != nil {
		return defaultValue
	}
	return int(i)
}

func getValueFromRow(row []string, index int) string {
	if index < len(row) {
		return strings.Replace(row[index], " ", "", -1)
	}
	return ""
}
